<template>
  <div class="exam-grading-page">
    <div class="page-header">
      <h2 class="page-title"><i class="fas fa-tasks"></i> 试题批改</h2>
      <div class="page-actions">
        <button @click="showExamSelectorModal = true" class="btn action-btn">
          <i class="fas fa-list-alt"></i> 选择考试
        </button>
        <button
          @click="openBatchGradeModal"
          class="btn btn-secondary action-btn"
          :disabled="selectedSubmissions.length === 0 || !currentExam"
          title="批量处理已选答卷"
        >
          <i class="fas fa-check-double"></i> 批量批改
        </button>
        <button @click="exportGradingReport" class="btn btn-info action-btn" :disabled="!currentExam || submissions.length === 0" title="导出当前考试的批改报告">
          <i class="fas fa-file-export"></i> 导出报告
        </button>
      </div>
    </div>

    <div v-if="currentExam" class="exam-dashboard">
      <div class="exam-info-card">
        <div class="exam-basic-info">
          <h3>{{ currentExam.name }}</h3>
          <div class="exam-meta">
            <span><i class="fas fa-calendar-alt"></i> {{ formatDate(currentExam.startTime) }}</span>
            <span><i class="fas fa-users"></i> {{ submissions.length }} 份答卷</span>
            <span><i class="fas fa-check-circle"></i> {{ gradedCount }} 已批改</span>
            <span><i class="fas fa-hourglass-start"></i> {{ pendingCount }} 待批改</span>
          </div>
        </div>
        <div class="grading-overall-progress">
            <ProgressBar :value="gradingProgress" />
        </div>
      </div>

      <div class="filter-controls-section">
        <select v-model="statusFilter" class="form-select filter-select">
          <option value="">所有状态</option>
          <option value="pending">待批改</option>
          <option value="graded">已批改</option>
          <option value="reviewed">已复核</option>
        </select>
        <select v-model="sortBy" class="form-select sort-select">
          <option value="submitTime">按提交时间</option>
          <option value="studentName">按学生姓名</option>
          <option value="score">按得分</option>
        </select>
        <div class="search-input-group">
          <input
            v-model.trim="searchQuery"
            placeholder="搜索学生姓名或学号..."
            @input="debouncedSearch"
            class="form-input search-input"
          />
          <i class="fas fa-search search-icon"></i>
        </div>
      </div>
    </div>
     <div v-else-if="!showExamSelectorModal" class="placeholder-view">
        <i class="fas fa-folder-open placeholder-icon"></i>
        <p>请点击“选择考试”开始批改。</p>
    </div>


    <div v-if="currentExam" class="submissions-list-section">
      <div v-if="filteredSubmissions.length > 0" class="submissions-grid">
        <SubmissionCard
          v-for="submission in filteredSubmissions"
          :key="submission.id"
          :submission="submission"
          :isSelected="selectedSubmissions.includes(submission.id)"
          @toggle-selection="toggleSubmissionSelection"
          @start-grading="handleStartGrading"
          @card-click="handleSubmissionCardClick"
        />
      </div>
      <div v-else class="no-submissions-found">
        <i class="fas fa-meh-blank"></i>
        <p>没有找到符合筛选条件的答卷。</p>
        <button v-if="searchQuery || statusFilter" @click="clearFilters" class="btn btn-sm btn-outline-secondary">清除筛选</button>
      </div>
    </div>


    <ExamSelector
      :show="showExamSelectorModal"
      :availableExams="availableExams"
      @update:show="showExamSelectorModal = $event"
      @select-exam="handleSelectExam"
      @page-change="handlePageChange"
      :totalItems="totalItems"
    />

    <BatchGradingModal
      :show="showBatchGradingModal"
      :selectedSubmissionsCount="selectedSubmissions.length"
      :options="batchGradingOptions"
      @update:show="showBatchGradingModal = $event"
      @process-batch-grading="handleProcessBatchGrading"
    />

    <GradingModal
      v-if="submissionForGrading"
      :show="showGradingModal"
      :submissionData="submissionForGrading"
      :submissionIndex="currentGradingSubmissionIndex"
      :totalSubmissionsInList="filteredSubmissions.length"
      :currentExamNameFromStore="currentExam ? currentExam.name : ''"
      @update:show="showGradingModal = $event"
      @save-submission="handleSaveGradedSubmission"
      @submit-submission="handleSubmitGradedSubmission"
      @navigate-submission="handleNavigateGradingSubmission"
    />
  </div>
  <Toast
   :toasts="toasts"
      @remove="removeToast"

  />
</template>

<script setup>
// ... (script remains the same)
import { ref, computed, onMounted } from 'vue';
import ExamSelector from './components/ExamSelector.vue';
import BatchGradingModal from './components/BatchGradingModal.vue';
import GradingModal from './components/GradingModal.vue';
import SubmissionCard from './components/SubmissionCard.vue';
import ProgressBar from './components/ProgressBar.vue';
import { formatDate, formatDuration, getStatusText, deepClone } from './utils';
import { ExamService } from '@/api/exam';
import Toast from '@/components/commont/Toast.vue';








const totalItems= ref(0); // Total number of exams, can be updated based on API response

const toasts = ref([])
// --- Reactive State ---
const currentExam = ref(null);
const submissions = ref([]);
const selectedSubmissions = ref([]);
const currentExamQuestion = ref([]);
const showExamSelectorModal = ref(false);
const showGradingModal = ref(false);
const showBatchGradingModal = ref(false);

const submissionForGrading = ref(null);
const currentGradingSubmissionIndex = ref(0);

const statusFilter = ref('');
const sortBy = ref('submitTime');
const searchQuery = ref('');
let searchTimeout = null;

const batchGradingOptions = ref({
  autoGradeObjective: true,
  zeroForBlank: true
});

const availableExams = ref([

  { id: 1,
   name: '2023年春季Java程序设计期末考试', startTime: '2023-06-01T09:00', endTime: '2023-06-01T11:00', status: '已结束', participantCount: 45, gradedCount: 0 },
  { id: 2, name: '2023年秋季Python数据分析中期测试', startTime: '2023-12-15T14:00', endTime: '2023-12-15T16:00', status: '已结束', participantCount: 32, gradedCount: 0 }
]);






const generateMockSubmissions = (examId) => {
  const mockSubmissions = [];
  const studentNames = ['张伟', '李娜', '王芳', '刘洋', '赵静', '陈晨', '孙悦', '周凯', '吴敏', '郑磊'];
  const baseTotalScore = 100;

  for (let i = 0; i < 10; i++) {
    const isGraded = Math.random() > 0.5;
    const questions = [
        { questionId: 1,
           type: '单选题',
           content: '在Java中，哪个关键字用于声明一个类不会被继承？ <code>final</code>, <code>static</code>, <code>abstract</code>, <code>private</code>',
           options: [
             { label: 'A', content: '<code>final</code>', isCorrect: true },
            { label: 'B', content: '<code>static</code>', isCorrect: false },
             { label: 'C', content: '<code>abstract</code>', isCorrect: false },
              { label: 'D', content: '<code>private</code>', isCorrect: false }
             ],
           studentAnswer: isGraded ? (Math.random() > 0.2 ? ['A'] : ['B']) : (Math.random() > 0.5 ? ['A'] : null),
           standardAnswer: 'A', maxScore: 20, score: null, comment: '' },
        { questionId: 2,
          type: '多选题',
           content: 'Python中哪些是内置的数据类型？ (至少选两项) <code>List</code>, <code>Array</code>, <code>Tuple</code>, <code>Dictionary</code>, <code>Set</code>',
            options: [ { label: 'A', content: '<code>List</code>', isCorrect: true },
             { label: 'B', content: '<code>Array</code> (from array module)', isCorrect: true },
             { label: 'C', content: '<code>Tuple</code>', isCorrect: true },
             { label: 'D', content: '<code>Dictionary</code>', isCorrect: true },
             { label: 'E', content: '<code>Set</code>', isCorrect: true } ],
             studentAnswer: isGraded ? (Math.random() > 0.3 ? ['A', 'C', 'D'] : ['A', 'B']) : (Math.random() > 0.5 ? ['A', 'C', 'D', 'E'] : []),
             standardAnswer: 'A,B,C,D,E', maxScore: 30, score: null, comment: '' },
        { questionId: 3, type: '填空题', content: 'HTML中用于定义超链接的标签是：&lt;___&gt;。', studentAnswer: isGraded ? (Math.random() > 0.4 ? 'a' : 'link') : (Math.random() > 0.3 ? 'a' : ''), standardAnswer: 'a', maxScore: 20, score: null, comment: '' },
        { questionId: 4, type: '简答题', content: '请简述TCP协议与UDP协议的主要区别及其应用场景。', studentAnswer: isGraded ? 'TCP是面向连接的，可靠的，如HTTP。UDP是无连接的，不可靠但高效，如视频流。' : (Math.random() > 0.2 ? 'TCP可靠，UDP快速。' : ''), standardAnswer: 'TCP：面向连接、可靠、有序、基于字节流；适用于文件传输、邮件、Web浏览。UDP：无连接、不可靠、无序、基于数据报；适用于实时音视频、DNS、DHCP。', maxScore: 30, score: null, comment: '' }
    ];

    let submissionScore = null;
    if (isGraded) {
        submissionScore = 0;
        questions.forEach(q => {
            if (q.type === '单选题') q.score = q.studentAnswer && q.studentAnswer[0] === q.standardAnswer ? q.maxScore : 0;
            else if (q.type === '多选题') {
                const correct = q.options.filter(opt => opt.isCorrect).map(opt => opt.label).sort();
                const student = (q.studentAnswer || []).sort();
                q.score = JSON.stringify(correct) === JSON.stringify(student) ? q.maxScore : (Math.random() > 0.5 ? q.maxScore / 2 : 0);
            } else {
                q.score = Math.floor(Math.random() * (q.maxScore * 0.8) + q.maxScore * 0.2); // Score between 20% and 100%
            }
            submissionScore += q.score;
        });
    }

    mockSubmissions.push({
      id: examId + i.toString(),
      paperId:'993150078766813184',
      examId,
      studentId: `S2023${String(i + 1).padStart(3, '0')}`,
      userId: studentNames[i % studentNames.length],
      submitTime: new Date(Date.now() - Math.random() * 10 * 24 * 60 * 60 * 1000).toISOString(),
      duration: Math.floor(Math.random() * 90) + 30, // 30-120 mins
      status: isGraded ? (Math.random() > 0.2 ? 'graded' : 'reviewed') : 'pending',
      score: isGraded ? submissionScore : null,
      totalScore: baseTotalScore,
      answers: questions.map(q => ({...q}))
    });
  }
  return mockSubmissions;
};

const filteredSubmissions = computed(() => {
  let result = [...submissions.value];
  if (statusFilter.value) {
    result = result.filter(s => s.status === statusFilter.value);
  }
  if (searchQuery.value) {
    const query = searchQuery.value.toLowerCase();
    result = result.filter(s =>
      s.userId.toLowerCase().includes(query) ||
      s.studentId.toLowerCase().includes(query)
    );
  }
  result.sort((a, b) => {
    switch (sortBy.value) {
      case 'userId': return a.userId.localeCompare(b.userId, 'zh-CN');
      case 'score': return (b.score ?? -1) - (a.score ?? -1);
      case 'submitTime':
      default: return new Date(b.submitTime).getTime() - new Date(a.submitTime).getTime();
    }
  });
  return result;
});

const gradedCount = computed(() => submissions.value.filter(s => s.status === 'graded' || s.status === 'reviewed').length);
const pendingCount = computed(() => submissions.value.filter(s => s.status === 'pending').length);
const gradingProgress = computed(() => {
  if (submissions.value.length === 0) return 0;
  return Math.round((gradedCount.value / submissions.value.length) * 100);
});

const showToast = (type, title, message) => {
 const toast = {
    id: Date.now(),
    type,
    title: title || `通知`,
    message: message,
    duration: 5000 // 5秒后自动关闭
  }
  toasts.value.push(toast)
  console.log(`[${type.toUpperCase()}] ${title}: ${message}`);

};

const  currentPage = ref(1);

const handlePageChange = (newPage) => {
  // Handle pagination logic here if needed

  currentPage.value = pageData.page;

loadExamData(newPage); // Load new page data

  console.log(`Page changed to: ${newPage}`);
};


const removeToast = (id) => {
  toasts.value = toasts.value.filter(toast => toast.id !== id)
}


const handleSelectExam = (exam) => {
  currentExam.value = exam;
  submissions.value = generateMockSubmissions(exam.id); //generateMockSubmissions(exam.id)
  selectedSubmissions.value = [];
  searchQuery.value = '';
  statusFilter.value = '';

  sortBy.value = 'submitTime';
   const examInList = availableExams.value.find(e => e.id === exam.id);
   if (examInList) {
       examInList.gradedCount = submissions.value.filter(s => s.status === 'graded' || s.status === 'reviewed').length;
   }
  showExamSelectorModal.value = false;
};

const toggleSubmissionSelection = (submissionId) => {
  const index = selectedSubmissions.value.indexOf(submissionId);
  if (index === -1) {
    selectedSubmissions.value.push(submissionId);
  } else {
    selectedSubmissions.value.splice(index, 1);
  }
};

const handleStartGrading = async(submission) => {
  submissionForGrading.value = deepClone(submission);

await getUserPaperDetail(submissionForGrading.value.paperId);

currentGradingSubmissionIndex.value = filteredSubmissions.value.findIndex(s => s.id === submission.id);

console.log('Current Exam Questions:', currentExamQuestion.value);

 submissionForGrading.value.answers=currentExamQuestion.value.flatMap(group => group.quList);

  console.log('submissionForGrading.value.answer:' , submissionForGrading.value);

  showGradingModal.value = true;
};



const getUserPaperDetail =async (paperId) => {
  await ExamService.getExamResult({ paperId })
  .then(response => {
    if (response && response.data) {
      showToast('success',response.data);
      console.log('获取答卷成功:', response.data);
const result= response.data;

currentExamQuestion.value=result.questionGroupList;
      console.log('获取答卷成功:', currentExamQuestion.value);

    } else {
      showToast('error', '获取答卷失败', '无法加载考试答卷数据，请稍后再试。');
    }
  })
  .catch(error => {
    console.error('获取答卷失败:', error);
    showToast('error', '获取答卷失败', '无法加载考试答卷数据，请稍后再试。');
  });


};


const handleSubmissionCardClick = (submission) => {
    // Optional: make card click also open grading, or just for selection highlight
    // handleStartGrading(submission);
};

const updateSubmissionInList = (updatedSubmission) => {
  const index = submissions.value.findIndex(s => s.id === updatedSubmission.id);
  if (index !== -1) {
    submissions.value.splice(index, 1, deepClone(updatedSubmission));
  }
  if (currentExam.value) {
    const examInList = availableExams.value.find(e => e.id === currentExam.value.id);
    if (examInList) {
        examInList.gradedCount = submissions.value.filter(s => s.status === 'graded' || s.status === 'reviewed').length;
    }
  }
};

const handleSaveGradedSubmission = (gradedSubmission) => {
  updateSubmissionInList(gradedSubmission);
  showToast('success', '保存成功', '批改结果已临时保存。');
};

const handleSubmitGradedSubmission = (submittedSubmission) => {
  updateSubmissionInList(submittedSubmission);
  showToast('success', '提交成功', `答卷 ${submittedSubmission.userId} (${submittedSubmission.studentId}) 批改已提交。`);

  if (currentGradingSubmissionIndex.value < filteredSubmissions.value.length - 1) {
    handleNavigateGradingSubmission('next');
  } else {
    showGradingModal.value = false;
    submissionForGrading.value = null;
    showToast('info', '批改完成', '当前列表所有答卷均已处理完毕。');
  }
};

const handleNavigateGradingSubmission = (direction) => {
  // Consider saving before navigating or prompting
  let newIndex = currentGradingSubmissionIndex.value;
  const currentList = filteredSubmissions.value; // Navigate within the currently filtered/sorted list

  if (direction === 'next' && newIndex < currentList.length - 1) {
    newIndex++;
  } else if (direction === 'previous' && newIndex > 0) {
    newIndex--;
  }

  // Update if index actually changed or if it's the first/last item and an explicit nav was made
  if (newIndex !== currentGradingSubmissionIndex.value ||
     (direction === 'next' && newIndex === currentList.length - 1 && currentList.length > 0) ||
     (direction === 'previous' && newIndex === 0 && currentList.length > 0) ) {
    currentGradingSubmissionIndex.value = newIndex;
    submissionForGrading.value = deepClone(currentList[newIndex]);
  } else if (direction === 'next' && newIndex >= currentList.length - 1) {
     showToast('info', '已是最后一份', '当前已是筛选列表中的最后一份答卷。');
  } else if (direction === 'previous' && newIndex <= 0) {
     showToast('info', '已是第一份', '当前已是筛选列表中的第一份答卷。');
  }
};


const openBatchGradeModal = () => {
  if (selectedSubmissions.value.length === 0) {
    showToast('warning', '操作无效', '请至少选择一份答卷进行批量批改。');
    return;
  }
  showBatchGradingModal.value = true;
};

const handleProcessBatchGrading = (options) => {
  const countToProcess = selectedSubmissions.value.length;
  if (countToProcess === 0) return;

  showToast('info', '批量批改中...', `正在处理 ${countToProcess} 份已选答卷...`);

  selectedSubmissions.value.forEach(submissionId => {
    const submission = submissions.value.find(s => s.id === submissionId);
    if (submission) {
      let totalScore = 0;
      submission.answers.forEach(answer => {
        let scoreAssignedThisPass = false; // Track if score was set by auto-grade
        if (options.autoGradeObjective && ['单选题', '多选题', '判断题'].includes(answer.type)) {
          let isCorrect = false;
          if (answer.type === '单选题') {
            isCorrect = answer.studentAnswer && answer.studentAnswer.length > 0 && answer.studentAnswer[0] === answer.standardAnswer;
          } else if (answer.type === '多选题') {
            const correctOpts = (answer.options || []).filter(opt => opt.isCorrect).map(opt => opt.label).sort();
            const studentOpts = (answer.studentAnswer || []).sort();
            isCorrect = JSON.stringify(correctOpts) === JSON.stringify(studentOpts) && correctOpts.length > 0;
          }
          answer.score = isCorrect ? answer.maxScore : 0;
          answer.comment = `批量自动批改：${isCorrect ? '正确' : '错误'}`;
          scoreAssignedThisPass = true;
        }

        if (!scoreAssignedThisPass && options.zeroForBlank && (!answer.studentAnswer || (Array.isArray(answer.studentAnswer) && answer.studentAnswer.length === 0) || (typeof answer.studentAnswer === 'string' && answer.studentAnswer.trim() === ''))) {
          answer.score = 0;
          answer.comment = '批量批改：未作答，记0分';
        }
        totalScore += (Number(answer.score) || 0);
      });
      submission.score = totalScore;
      submission.status = 'graded'; // Mark all batch-processed as graded
      updateSubmissionInList(submission);
    }
  });

  const processedCount = selectedSubmissions.value.length; // Re-capture length in case it changes during processing (it shouldn't here)
  selectedSubmissions.value = [];
  showToast('success', '批量批改完成', `已成功批改 ${processedCount} 份答卷。`);
};

const exportGradingReport = () => {
  if (!currentExam.value || submissions.value.length === 0) {
    showToast('warning', '无数据导出', '当前考试没有可导出的批改数据。');
    return;
  }
  const reportData = submissions.value.map(s => ({
    学号: s.studentId,
    姓名: s.userId,
    提交时间: formatDate(s.submitTime),
    答题用时: formatDuration(s.duration),
    得分: s.score ?? '未批改',
    总分: s.totalScore,
    状态: getStatusText(s.status)
  }));

  const headers = Object.keys(reportData[0]).join(',');
  const rows = reportData.map(row => Object.values(row).map(val => `"${String(val ?? '').replace(/"/g, '""')}"`).join(',')).join('\n');
  const csvContent = "\uFEFF" + headers + '\n' + rows;

  const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
  const url = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = url;
  link.setAttribute('download', `[${currentExam.value.name}]批改报告_${new Date().toLocaleDateString().replace(/\//g, '-')}.csv`);
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
  showToast('success', '导出成功', '批改报告已生成并开始下载。');
};

const debouncedSearch = () => {
  clearTimeout(searchTimeout);
  searchTimeout = setTimeout(() => { /* Computed property handles filtering */ }, 300);
};

const clearFilters = () => {
    searchQuery.value = '';
    statusFilter.value = '';
    // sortBy.value = 'submitTime'; // Optionally reset sort
};

const loadExamData = (page) => {
  // Simulate fetching exam data from an API or store
  // For now, we use the mock data defined above

      ExamService.getExam({page:page,pageSize:10}).then(response => {

      availableExams.value = response.data.records.map(exam => ({
        ...exam,
        gradedCount: 0 // Initialize graded count
      }));
      totalItems.value = response.data.total; // Update total items for pagination


  }).catch(error => {
    console.error('Error loading exams:', error);
    showToast('error', '加载考试失败', '网络错误或服务器异常，请稍后再试。');
  });

};


onMounted(() => {
  if (!currentExam.value) {
    showExamSelectorModal.value = true;
  }

  loadExamData(1); // Load initial exam data, consider passing page number if paginated
});
</script>

<style scoped>
/* Global Page Styles */
:root { /* Define these in a global CSS if possible */
  --primary-color: #007bff;
  --secondary-color: #6c757d;
  --success-color: #28a745;
  --info-color: #17a2b8;
  --warning-color: #ffc107;
  --danger-color: #dc3545;
  --light-color: #f8f9fa;
  --dark-color: #343a40;
  --text-color: #212529;
  --text-muted-color: #6c757d;
  --border-color: #dee2e6;
  --background-color: #f4f6f8; /* Page background */
  --card-bg: #ffffff;
  --border-radius: 0.25rem;
  --box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
}

.exam-grading-page {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  background-color: var(--background-color);
  padding: 1.5rem;
  min-height: 100vh;
  color: var(--text-color);
}

/* Page Header */
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.5rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--border-color);
}
.page-title {
  font-size: 1.75rem;
  font-weight: 600;
  color: var(--dark-color);
  margin: 0;
}
.page-title i {
    margin-right: 0.75rem;
    color: var(--primary-color);
}
.page-actions {
  display: flex;
  gap: 0.75rem;
}

/* Buttons (Base Styling) */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem 1rem;
  font-size: 0.9rem;
  font-weight: 500;
  border-radius: var(--border-radius);
  cursor: pointer;
  text-decoration: none;
  border: 1px solid transparent;
  transition: all 0.2s ease-in-out;
  white-space: nowrap;
}
.btn i { margin-right: 0.4rem; }
.btn:disabled { opacity: 0.65; cursor: not-allowed; }

.btn-primary { background-color: var(--primary-color); color: white; border-color: var(--primary-color); }
.btn-primary:hover:not(:disabled) { background-color: #0056b3; border-color: #0056b3; }
.btn-secondary { background-color: var(--secondary-color); color: white; border-color: var(--secondary-color); }
.btn-secondary:hover:not(:disabled) { background-color: #545b62; border-color: #545b62; }
.btn-info { background-color: var(--info-color); color: white; border-color: var(--info-color); }
.btn-info:hover:not(:disabled) { background-color: #117a8b; border-color: #117a8b; }
.btn-sm { padding: 0.375rem 0.75rem; font-size: 0.8rem; }
.btn-outline-secondary { color: var(--secondary-color); border-color: var(--secondary-color); background-color: transparent; }
.btn-outline-secondary:hover { color: white; background-color: var(--secondary-color); }


/* Exam Dashboard (Info + Filters) */
.exam-dashboard {
  background-color: var(--card-bg);
  padding: 1.25rem;
  border-radius: var(--border-radius);
  box-shadow: var(--box-shadow);
  margin-bottom: 1.5rem;
}
.exam-info-card {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.25rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--border-color);
}
.exam-basic-info h3 {
  font-size: 1.4rem;
  margin: 0 0 0.5rem 0;
  color: var(--primary-color);
}
.exam-meta { display: flex; gap: 1rem; font-size: 0.875rem; color: var(--text-muted-color); }
.exam-meta span i { margin-right: 0.3rem; }
.grading-overall-progress { width: 250px; }


/* Filter Controls */
.filter-controls-section {
  display: flex;
  gap: 1rem;
  align-items: center;
}
.form-select, .form-input {
  padding: 0.5rem 0.75rem;
  font-size: 0.9rem;
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius);
  background-color: #fff;
  color: var(--text-color);
  height: 38px; /* Consistent height */
}
.form-select:focus, .form-input:focus {
  border-color: var(--primary-color);
  box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25);
  outline: none;
}
.filter-select { flex-basis: 180px; }
.sort-select { flex-basis: 180px; }
.search-input-group { position: relative; flex-grow: 1; max-width: 350px; }
.search-input { width: 100%; padding-right: 2.5rem; /* Space for icon */ }
.search-icon {
  position: absolute;
  right: 0.75rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted-color);
}

/* Submissions List */
.submissions-list-section { margin-top: 1.5rem; }
.submissions-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); /* Responsive grid */
  gap: 1.5rem;
}

/* Placeholder / No Data States */
.placeholder-view, .no-submissions-found {
  text-align: center;
  padding: 3rem 1rem;
  color: var(--text-muted-color);
  background-color: var(--card-bg);
  border-radius: var(--border-radius);
  box-shadow: var(--box-shadow);
  margin-top: 2rem;
}
.placeholder-icon, .no-submissions-found i.fas {
  font-size: 3rem;
  margin-bottom: 1rem;
  color: #adb5bd;
}
.placeholder-view p, .no-submissions-found p {
  font-size: 1.1rem;
  margin-bottom: 1rem;
}
.no-submissions-found button { margin-top: 0.5rem; }

/* Ensure modals are styled by their own components or global styles */
</style>
